package com.mldong.base;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mldong.log.LogHolder;
import com.mldong.log.LogParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
@ApiModel
public class PageParam<T> {
    @ApiModelProperty(value = "当前页码")
    private Integer pageNum;
    @ApiModelProperty(value = "每页大小")
    private Integer pageSize;
    @ApiModelProperty(value="排序字段")
    private String orderBy;
    @ApiModelProperty("是否查询总数")
    private Boolean isCount;
    final static String REG_EXP = "(^_([a-zA-Z0-9\\s]_?)*$)|(^[a-zA-Z\\.](_?[a-zA-Z0-9\\.\\s])*_?$)";
    /**
     * 构建mybatis-plus分页对象
     * @return
     */
    public IPage buildMpPage() {
        if(pageNum==null) {
            this.pageNum = 1;
        }
        if(pageSize == null) {
            this.pageSize = 10;
        }
        IPage page = new Page(getPageNum(),getPageSize(), !Boolean.FALSE.equals(isCount));
        return page;
    }

    /**
     * 构建查询条件
     * @return
     */
    public QueryWrapper buildQueryWrapper() {
        QueryWrapper queryWrapper = Wrappers.query();
        // 获取所有属性m_{type}_{column}
        // 有表别名时m_{alias}_{type}_{column}
        // Field fields [] = ReflectUtil.getFields(this.getClass());
        LogParam logParam = LogHolder.get();
        String body = "";
        if(logParam!=null) {
            body = logParam.getBody();
        }
        Dict dict = Dict.create();
        if(JSONUtil.isTypeJSONObject(body)) {
            dict.putAll(JSONUtil.toBean(body,Dict.class));
        }
        String thisJsonStr = JSONUtil.toJsonStr(this);
        Dict thisDict = JSONUtil.toBean(thisJsonStr,Dict.class);
        dict.putAll(thisDict);
        Object [] keys = dict.keySet().toArray();
        for (int i = 0; i < keys.length ; i++) {
            // Field field = fields[i];
            String fieldName = keys[i].toString();
            if(!fieldName.startsWith("m_")) continue;
            if(!fieldName.matches(REG_EXP)) continue;
            String arr [] = fieldName.split("_");
            if(arr.length !=3 && arr.length!=4) continue;
            String type = "";
            String column = "";
            if(arr.length == 3) {
                type = arr[1];
                column = StrUtil.toUnderlineCase(arr[2]);
            } else {
                type = arr[2];
                column = arr[1] + "." + StrUtil.toUnderlineCase(arr[3]);
            }
            Object fieldValue = dict.get(fieldName);
            if(ObjectUtil.isEmpty(fieldValue)) continue;

            switch (type){
                case "EQ":
                    queryWrapper.eq(column, fieldValue);
                    break;
                case "NE":
                    queryWrapper.ne(column, fieldValue);
                    break;
                case "GT":
                    queryWrapper.gt(column, fieldValue);
                    break;
                case "GE":
                    queryWrapper.ge(column, fieldValue);
                    break;
                case "LT":
                    queryWrapper.lt(column, fieldValue);
                    break;
                case "LE":
                    queryWrapper.le(column, fieldValue);
                    break;
                case "LIKE":
                    queryWrapper.like(column, fieldValue);
                    break;
                case "NLIKE":
                    queryWrapper.notLike(column, fieldValue);
                    break;
                case "LLIKE":
                    queryWrapper.likeLeft(column, fieldValue);
                    break;
                case "RLIKE":
                    queryWrapper.likeRight(column, fieldValue);
                    break;
                case "BT":
                    if(fieldValue instanceof List) {
                        List btValue = Convert.toList(fieldValue);
                        if(btValue.size()==2) {
                            Object btValue1 = btValue.get(0);
                            Object btValue2 = btValue.get(1);
                            queryWrapper.between(column, btValue1, btValue2);
                        }
                    } else if(fieldValue instanceof String) {
                        String btArr [] = ((String) fieldValue).split(",");
                        Object btValue1 = btArr[0];
                        Object btValue2 = btArr[1];
                        queryWrapper.between(column, btValue1, btValue2);
                     }
                    break;
                case "IN":
                    if(fieldValue instanceof List) {
                        List inValue = Convert.toList(fieldValue);
                        queryWrapper.in(column, inValue);
                    } else if(fieldValue instanceof String) {
                        String btArr [] = ((String) fieldValue).split(",");
                        queryWrapper.in(column, CollectionUtil.toList(btArr));
                    }
                    break;
                case "NIN":
                    if(fieldValue instanceof List) {
                        List inValue = Convert.toList(fieldValue);
                        queryWrapper.notIn(column, inValue);
                    } else if(fieldValue instanceof String) {
                        String btArr [] = ((String) fieldValue).split(",");
                        queryWrapper.notIn(column, CollectionUtil.toList(btArr));
                    }
                    break;
            }
        }
        // 构建排序
        // id desc
        // id asc
        // id desc,code asc
        // id,code asc
        if(StrUtil.isEmpty(orderBy)) return queryWrapper;
        String arr [] = orderBy.split(",");
        for(String s:arr) {
            String orderByList [] = s.split("\\s+");
            if (orderByList.length==1) {
                String column = StrUtil.toUnderlineCase(orderByList[0]);
                if (column.matches(REG_EXP)) {
                    queryWrapper.orderByAsc(column);
                }
            } else {
                String column = StrUtil.toUnderlineCase(orderByList[0]);
                if (column.matches(REG_EXP)) {
                    if("desc".equalsIgnoreCase(orderByList[1])) {
                        queryWrapper.orderByDesc(column);
                    } else {
                        queryWrapper.orderByAsc(column);
                    }
                }
            }
        }
        return queryWrapper;
    }
}
